home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / LIGHTLAB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  7.5 KB  |  285 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include <stdarg.h>
  10. #include <stdio.h>
  11. #include <GL/glut.h>
  12.  
  13. enum {
  14.   BRASS, RED_PLASTIC, EMERALD, SLATE
  15. } MaterialType;
  16. enum {
  17.   TORUS_MATERIAL = 1, TEAPOT_MATERIAL = 2, ICO_MATERIAL = 3
  18. } MaterialDisplayList;
  19. enum {
  20.   LIGHT_OFF, LIGHT_RED, LIGHT_WHITE, LIGHT_GREEN
  21. } LightValues;
  22.  
  23. GLfloat red_light[] =
  24. {1.0, 0.0, 0.0, 1.0}, green_light[] =
  25. {0.0, 1.0, 0.0, 1.0}, white_light[] =
  26. {1.0, 1.0, 1.0, 1.0};
  27. GLfloat left_light_position[] =
  28. {-1.0, 0.0, 1.0, 0.0}, right_light_position[] =
  29. {1.0, 0.0, 1.0, 0.0};
  30. GLfloat brass_ambient[] =
  31. {0.33, 0.22, 0.03, 1.0}, brass_diffuse[] =
  32. {0.78, 0.57, 0.11, 1.0}, brass_specular[] =
  33. {0.99, 0.91, 0.81, 1.0}, brass_shininess = 27.8;
  34. GLfloat red_plastic_ambient[] =
  35. {0.0, 0.0, 0.0}, red_plastic_diffuse[] =
  36. {0.5, 0.0, 0.0}, red_plastic_specular[] =
  37. {0.7, 0.6, 0.6}, red_plastic_shininess = 32.0;
  38. GLfloat emerald_ambient[] =
  39. {0.0215, 0.1745, 0.0215}, emerald_diffuse[] =
  40. {0.07568, 0.61424, 0.07568}, emerald_specular[] =
  41. {0.633, 0.727811, 0.633}, emerald_shininess = 76.8;
  42. GLfloat slate_ambient[] =
  43. {0.02, 0.02, 0.02}, slate_diffuse[] =
  44. {0.02, 0.01, 0.01}, slate_specular[] =
  45. {0.4, 0.4, 0.4}, slate_shininess = .78125;
  46. int shade_model = GL_SMOOTH;
  47. char *left_light, *right_light;
  48. char *ico_material, *teapot_material, *torus_material;
  49.  
  50. void 
  51. output(GLfloat x, GLfloat y, char *format,...)
  52. {
  53.   va_list args;
  54.   char buffer[200], *p;
  55.  
  56.   va_start(args, format);
  57.   vsprintf(buffer, format, args);
  58.   va_end(args);
  59.   glPushMatrix();
  60.   glTranslatef(x, y, 0);
  61.   for (p = buffer; *p; p++)
  62.     glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
  63.   glPopMatrix();
  64. }
  65.  
  66. void 
  67. display(void)
  68. {
  69.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  70.   glMatrixMode(GL_MODELVIEW);
  71.   glPushMatrix();
  72.   glScalef(1.3, 1.3, 1.3);
  73.   glRotatef(20.0, 1.0, 0.0, 0.0);
  74.   glPushMatrix();
  75.   glTranslatef(-0.65, 0.7, 0.0);
  76.   glRotatef(90.0, 1.0, 0.0, 0.0);
  77.   glCallList(TORUS_MATERIAL);
  78.   glutSolidTorus(0.275, 0.85, 10, 15);
  79.   glPopMatrix();
  80.   glPushMatrix();
  81.   glTranslatef(-0.75, -0.8, 0.0);
  82.   glCallList(TEAPOT_MATERIAL);
  83.   glutSolidTeapot(0.7);
  84.   glPopMatrix();
  85.   glPushMatrix();
  86.   glTranslatef(1.0, 0.0, -1.0);
  87.   glCallList(ICO_MATERIAL);
  88.   glutSolidIcosahedron();
  89.   glPopMatrix();
  90.   glPopMatrix();
  91.   glPushAttrib(GL_ENABLE_BIT);
  92.   glDisable(GL_DEPTH_TEST);
  93.   glDisable(GL_LIGHTING);
  94.   glMatrixMode(GL_PROJECTION);
  95.   glPushMatrix();
  96.   glLoadIdentity();
  97.   gluOrtho2D(0, 3000, 0, 3000);
  98.   glMatrixMode(GL_MODELVIEW);
  99.   glPushMatrix();
  100.   glLoadIdentity();
  101.   output(80, 2800, "Torus: %s", torus_material);
  102.   output(80, 2650, "Icosahedron: %s", ico_material);
  103.   output(80, 2500, "Teapot: %s", teapot_material);
  104.   output(80, 250, "Left light: %s", left_light);
  105.   output(1700, 250, "Right light: %s", right_light);
  106.   output(850, 100, "Shade model: %s",
  107.     shade_model == GL_SMOOTH ? "smooth" : "flat");
  108.   glPopMatrix();
  109.   glMatrixMode(GL_PROJECTION);
  110.   glPopMatrix();
  111.   glPopAttrib();
  112.   glutSwapBuffers();
  113. }
  114.  
  115. void 
  116. light_select(GLenum which, int value, char **label)
  117. {
  118.   glEnable(which);
  119.   switch (value) {
  120.   case LIGHT_OFF:
  121.     *label = "off";
  122.     glDisable(which);
  123.     break;
  124.   case LIGHT_RED:
  125.     *label = "red";
  126.     glLightfv(which, GL_DIFFUSE, red_light);
  127.     break;
  128.   case LIGHT_WHITE:
  129.     *label = "white";
  130.     glLightfv(which, GL_DIFFUSE, white_light);
  131.     break;
  132.   case LIGHT_GREEN:
  133.     *label = "green";
  134.     glLightfv(which, GL_DIFFUSE, green_light);
  135.     break;
  136.   }
  137.   glutPostRedisplay();
  138. }
  139.  
  140. void 
  141. left_light_select(int value)
  142. {
  143.   light_select(GL_LIGHT0, value, &left_light);
  144. }
  145.  
  146. void 
  147. right_light_select(int value)
  148. {
  149.   light_select(GL_LIGHT1, value, &right_light);
  150. }
  151.  
  152. void 
  153. material(int dlist, GLfloat * ambient, GLfloat * diffuse,
  154.   GLfloat * specular, GLfloat shininess)
  155. {
  156.   glNewList(dlist, GL_COMPILE);
  157.   glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
  158.   glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
  159.   glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
  160.   glMaterialf(GL_FRONT, GL_SHININESS, shininess);
  161.   glEndList();
  162. }
  163.  
  164. char *
  165. material_select(int object, int value)
  166. {
  167.   glutPostRedisplay();
  168.   switch (value) {
  169.   case BRASS:
  170.     material(object, brass_ambient,
  171.       brass_diffuse, brass_specular, brass_shininess);
  172.     return "brass";
  173.   case RED_PLASTIC:
  174.     material(object, red_plastic_ambient, red_plastic_diffuse,
  175.       red_plastic_specular, red_plastic_shininess);
  176.     return "red plastic";
  177.   case EMERALD:
  178.     material(object, emerald_ambient, emerald_diffuse,
  179.       emerald_specular, emerald_shininess);
  180.     return "emerald";
  181.   case SLATE:
  182.     material(object, slate_ambient, slate_diffuse,
  183.       slate_specular, slate_shininess);
  184.     return "slate";
  185.   }
  186.   return NULL; /* avoid bogus warning! */
  187. }
  188.  
  189. void 
  190. torus_select(int value)
  191. {
  192.   torus_material = material_select(TORUS_MATERIAL, value);
  193. }
  194.  
  195. void 
  196. teapot_select(int value)
  197. {
  198.   teapot_material = material_select(TEAPOT_MATERIAL, value);
  199. }
  200.  
  201. void 
  202. ico_select(int value)
  203. {
  204.   ico_material = material_select(ICO_MATERIAL, value);
  205. }
  206.  
  207. void 
  208. main_menu_select(int value)
  209. {
  210.   if (value == 666)
  211.     exit(0);
  212.   glShadeModel(shade_model = value);
  213.   glutPostRedisplay();
  214. }
  215.  
  216. int 
  217. main(int argc, char **argv)
  218. {
  219.   int left_light_m, right_light_m, torus_m, teapot_m, ico_m;
  220.  
  221.   glutInitWindowSize(400, 400);
  222.   glutInit(&argc, argv);
  223.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  224.   glutCreateWindow("Lighting Laboratory");
  225.   glutDisplayFunc(display);
  226.  
  227. #define LIGHT_MENU_ENTRIES() \
  228.     glutAddMenuEntry("Disable", LIGHT_OFF); \
  229.     glutAddMenuEntry("Red", LIGHT_RED); \
  230.     glutAddMenuEntry("White", LIGHT_WHITE); \
  231.     glutAddMenuEntry("Green", LIGHT_GREEN);
  232. #define MATERIAL_MENU_ENTRIES() \
  233.     glutAddMenuEntry("Brass", BRASS); \
  234.     glutAddMenuEntry("Red plastic", RED_PLASTIC); \
  235.     glutAddMenuEntry("Emerald", EMERALD); \
  236.     glutAddMenuEntry("Slate", SLATE);
  237.  
  238.   left_light_m = glutCreateMenu(left_light_select);
  239.   LIGHT_MENU_ENTRIES();
  240.   right_light_m = glutCreateMenu(right_light_select);
  241.   LIGHT_MENU_ENTRIES();
  242.   torus_m = glutCreateMenu(torus_select);
  243.   MATERIAL_MENU_ENTRIES();
  244.   teapot_m = glutCreateMenu(teapot_select);
  245.   MATERIAL_MENU_ENTRIES();
  246.   ico_m = glutCreateMenu(ico_select);
  247.   MATERIAL_MENU_ENTRIES();
  248.  
  249.   glutCreateMenu(main_menu_select);
  250.   glutAddMenuEntry("Smooth shading", GL_SMOOTH);
  251.   glutAddMenuEntry("Flat shading", GL_FLAT);
  252.   glutAddSubMenu("Left light", left_light_m);
  253.   glutAddSubMenu("Right light", right_light_m);
  254.   glutAddSubMenu("Torus", torus_m);
  255.   glutAddSubMenu("Teapot", teapot_m);
  256.   glutAddSubMenu("Icosahedron", ico_m);
  257.   glutAddMenuEntry("Quit", 666);
  258.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  259.  
  260.   glLightfv(GL_LIGHT0, GL_POSITION, left_light_position);
  261.   glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
  262.   glLightfv(GL_LIGHT1, GL_POSITION, right_light_position);
  263.   glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);
  264.   left_light_select(LIGHT_RED);
  265.   right_light_select(LIGHT_GREEN);
  266.   torus_select(RED_PLASTIC);
  267.   teapot_select(BRASS);
  268.   ico_select(EMERALD);
  269.   glEnable(GL_LIGHTING);
  270.   glEnable(GL_DEPTH_TEST);
  271.   glEnable(GL_NORMALIZE);
  272.   glLineWidth(1.0);
  273.   glMatrixMode(GL_PROJECTION);
  274.   gluPerspective( /* degrees field of view */ 50.0,
  275.     /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0);
  276.   glMatrixMode(GL_MODELVIEW);
  277.   gluLookAt(0.0, 0.0, 5.0,  /* eye is at (0,0,5) */
  278.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  279.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  280.   glTranslatef(0.0, 0.0, -1.0);
  281.  
  282.   glutMainLoop();
  283.   return 0;             /* ANSI C requires main to return int. */
  284. }
  285.